#include "databasemanager.h"
#include <QSqlRecord>
#include <QDebug>
#include <QDateTime>

DatabaseManager* DatabaseManager::s_instance = nullptr;

DatabaseManager* DatabaseManager::instance()
{
    if (!s_instance) {
        s_instance = new DatabaseManager();
    }
    return s_instance;
}

DatabaseManager::DatabaseManager(QObject *parent) : QObject(parent)
{
}

DatabaseManager::~DatabaseManager()
{
    if (m_db.isOpen()) {
        m_db.close();
    }
}

bool DatabaseManager::initialize(const QString& dbName)
{
    m_dbName = dbName;
    m_db = QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName(m_dbName);

    if (!m_db.open()) {
        m_lastError = m_db.lastError().text();
        qWarning() << "Failed to open database:" << m_lastError;
        return false;
    }

    return createTables();
}

bool DatabaseManager::createTables()
{
    // 创建当前车辆表
    QString sql = "CREATE TABLE IF NOT EXISTS curInfo ("
                  "carid TEXT PRIMARY KEY, "
                  "enterTime TEXT NOT NULL)";
    if (!execute(sql)) {
        return false;
    }

    // 创建历史记录表
    sql = "CREATE TABLE IF NOT EXISTS recordInfo ("
          "id INTEGER PRIMARY KEY AUTOINCREMENT, "
          "carid TEXT NOT NULL, "
          "enterTime TEXT NOT NULL, "
          "lastTime TEXT NOT NULL, "
          "sece INTEGER NOT NULL, "
          "money REAL NOT NULL)";
    if (!execute(sql)) {
        return false;
    }

    // 创建VIP记录表
    sql = "CREATE TABLE IF NOT EXISTS vipInfo ("
          "id INTEGER PRIMARY KEY AUTOINCREMENT, "
          "carid TEXT NOT NULL, "
          "enterTime TEXT NOT NULL, "
          "lastTime TEXT NOT NULL, "
          "sece INTEGER NOT NULL, "
          "money REAL NOT NULL)";
    if (!execute(sql)) {
        return false;
    }

    // 创建用户表
    sql = "CREATE TABLE IF NOT EXISTS userInfo ("
          "account TEXT PRIMARY KEY, "
          "password TEXT NOT NULL)";
    if (!execute(sql)) {
        return false;
    }

    // 创建车位表
    sql = "CREATE TABLE IF NOT EXISTS parking_slots ("
          "slot_number INTEGER PRIMARY KEY, "
          "carid TEXT, "
          "enter_time TEXT)";
    if (!execute(sql)) {
        return false;
    }

    // 初始化管理员账户
    if (!tableExists("userInfo") || getCurrentCarCount() == 0) {
        addUser("admin", "123456");
    }

    return true;
}

bool DatabaseManager::execute(const QString& sql, const QVariantMap& params)
{
    QSqlQuery query(m_db);
    query.prepare(sql);

    for (auto it = params.constBegin(); it != params.constEnd(); ++it) {
        query.bindValue(":" + it.key(), it.value());
    }

    if (!query.exec()) {
        m_lastError = query.lastError().text();
        qWarning() << "SQL error:" << m_lastError << "in query:" << sql;
        return false;
    }

    return true;
}

QVector<QVariantMap> DatabaseManager::query(const QString& sql, const QVariantMap& params)
{
    QVector<QVariantMap> results;
    QSqlQuery query(m_db);
    query.prepare(sql);

    for (auto it = params.constBegin(); it != params.constEnd(); ++it) {
        query.bindValue(":" + it.key(), it.value());
    }

    if (!query.exec()) {
        m_lastError = query.lastError().text();
        qWarning() << "SQL error:" << m_lastError << "in query:" << sql;
        return results;
    }

    while (query.next()) {
        QVariantMap record;
        QSqlRecord sqlRecord = query.record();
        for (int i = 0; i < sqlRecord.count(); ++i) {
            record[sqlRecord.fieldName(i)] = query.value(i);
        }
        results.append(record);
    }

    return results;
}

bool DatabaseManager::addCar(const QString& carId, const QString& enterTime)
{
    QVariantMap params;
    params["carid"] = carId;
    params["enterTime"] = enterTime;

    QString sql = "INSERT INTO curInfo (carid, enterTime) "
                  "VALUES (:carid, :enterTime)";

    return execute(sql, params);
}

bool DatabaseManager::removeCar(const QString& carId)
{
    QVariantMap params;
    params["carid"] = carId;

    QString sql = "DELETE FROM curInfo WHERE carid = :carid";
    return execute(sql, params);
}

bool DatabaseManager::addParkingRecord(const QString& carId, const QString& enterTime,
                                      const QString& lastTime, int seconds, double money, bool isVip)
{
    QVariantMap params;
    params["carid"] = carId;
    params["enterTime"] = enterTime;
    params["lastTime"] = lastTime;
    params["sece"] = seconds;
    params["money"] = money;

    QString table = isVip ? "vipInfo" : "recordInfo";
    QString sql = QString("INSERT INTO %1 (carid, enterTime, lastTime, sece, money) "
                          "VALUES (:carid, :enterTime, :lastTime, :sece, :money)").arg(table);

    return execute(sql, params);
}

bool DatabaseManager::isCarInParking(const QString& carId)
{
    QVariantMap params;
    params["carid"] = carId;

    QString sql = "SELECT 1 FROM curInfo WHERE carid = :carid";
    return !query(sql, params).isEmpty();
}

int DatabaseManager::getCurrentCarCount()
{
    QString sql = "SELECT COUNT(*) FROM curInfo";
    QVector<QVariantMap> result = query(sql);

    if (result.isEmpty()) {
        return 0;
    }

    return result.first().value("COUNT(*)").toInt();
}

QVector<QVariantMap> DatabaseManager::getCurrentCars()
{
    QString sql = "SELECT * FROM curInfo";
    return query(sql);
}

QVector<QVariantMap> DatabaseManager::getHistoryRecords(bool vipOnly)
{
    QString table = vipOnly ? "vipInfo" : "recordInfo";
    QString sql = QString("SELECT * FROM %1 ORDER BY lastTime DESC").arg(table);
    return query(sql);
}

bool DatabaseManager::updateParkingSlots(int totalSlots)
{
    // 先删除所有现有车位
    if (!execute("DELETE FROM parking_slots")) {
        return false;
    }

    // 插入新的车位
    for (int i = 1; i <= totalSlots; ++i) {
        QVariantMap params;
        params["slot_number"] = i;

        QString sql = "INSERT INTO parking_slots (slot_number) VALUES (:slot_number)";
        if (!execute(sql, params)) {
            return false;
        }
    }

    return true;
}

QVector<QVariantMap> DatabaseManager::getParkingSlotsInfo()
{
    QString sql = "SELECT * FROM parking_slots ORDER BY slot_number";
    return query(sql);
}

bool DatabaseManager::assignCarToSlot(const QString& carId, int slotNumber, const QString& enterTime)
{
    QVariantMap params;
    params["carid"] = carId;
    params["slot_number"] = slotNumber;
    params["enter_time"] = enterTime;

    QString sql = "UPDATE parking_slots SET carid = :carid, enter_time = :enter_time "
                  "WHERE slot_number = :slot_number";

    return execute(sql, params);
}

bool DatabaseManager::freeParkingSlot(int slotNumber)
{
    QVariantMap params;
    params["slot_number"] = slotNumber;

    QString sql = "UPDATE parking_slots SET carid = NULL, enter_time = NULL "
                  "WHERE slot_number = :slot_number";

    return execute(sql, params);
}

bool DatabaseManager::addUser(const QString& account, const QString& password)
{
    QVariantMap params;
    params["account"] = account;
    params["password"] = password;

    QString sql = "INSERT OR REPLACE INTO userInfo (account, password) "
                  "VALUES (:account, :password)";

    return execute(sql, params);
}

bool DatabaseManager::validateUser(const QString& account, const QString& password)
{
    QVariantMap params;
    params["account"] = account;
    params["password"] = password;

    QString sql = "SELECT 1 FROM userInfo WHERE account = :account AND password = :password";
    return !query(sql, params).isEmpty();
}

bool DatabaseManager::tableExists(const QString& tableName)
{
    QString sql = "SELECT name FROM sqlite_master WHERE type='table' AND name=?";
    QSqlQuery query(m_db);
    query.prepare(sql);
    query.addBindValue(tableName);

    if (!query.exec()) {
        return false;
    }

    return query.next();
}
